<?php
declare(strict_types=1);

namespace Zms\AdminHelper;

use Hyperf\HttpServer\Contract\RequestInterface;
use Hyperf\Context\ApplicationContext;
use Jenssegers\Agent\Agent;
use JetBrains\PhpStorm\ArrayShape;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;

class Client
{
    /**
     * 获取浏览器标识
     * @param string|null $agent
     * @return string
     */
    public static function getAgent(string $agent = null): string
    {
        return $agent ?: (self::getRequest()->getHeader('user-agent')[0] ?? '');
    }


    /**
     * 获取request对象
     * @return ?RequestInterface
     * @author 竹林风@875384189 2021/3/11 11:53
     */
    private static function getRequest(): ?RequestInterface
    {
        try {
            return ApplicationContext::getContainer()->get(RequestInterface::class);
        } catch (NotFoundExceptionInterface|ContainerExceptionInterface) {
            return null;
        }
    }


    /**
     * 操作系统
     */
    public static function os(?string $agent = null): string
    {
        $agent = self::getAgent($agent);
        if ($agent) {
            if (false !== stripos($agent, 'win')) {
                if (preg_match('/nt 6.1/i', $agent)) return 'Windows7';
                if (preg_match('/nt 6.2/i', $agent)) return 'Windows8';
                if (preg_match('/nt 10.0/i', $agent)) return 'Windows10';
                if (preg_match('/nt 5.1/i', $agent)) return 'WindowsXp';
            }
            if (false !== stripos($agent, 'deepin')) return 'Deepin';
            if (false !== stripos($agent, 'uos')) return 'Uos';
            if (false !== stripos($agent, 'ubuntu')) return 'Ubuntu';
            if (false !== stripos($agent, 'cros')) return 'FydeOs';
            if (false !== stripos($agent, 'harmony')) return 'HarmonyOs';
            if (false !== stripos($agent, 'android')) return 'Android';
            if (false !== stripos($agent, 'linux')) return 'Linux';
            if (false !== stripos($agent, 'iphone')) return 'Ios';
            if (false !== stripos($agent, 'ipad')) return 'IpadOs';
            if (false !== stripos($agent, 'mac')) return 'MacOs';
            $agentServer = new Agent;
            $agentServer->setUserAgent($agent);
            return $agentServer->platform() ?: '其他';
        }
        return '其他';
    }


    /**
     * 获取浏览器
     * @param ?string $userAgent
     * @return string
     */
    public static function browser(?string $userAgent = null): string
    {
        return self::info($userAgent)['browser'];
    }


    /**
     * 解析用户访问信息
     * @param string|null $userAgent
     * @return array
     */
    #[ArrayShape([
        'agent' => 'string', 'os' => 'string', 'browser' => 'string', 'mobile' => 'integer', 'robot' => 'integer', 'device' => 'string'
    ])]
    public static function info(?string $userAgent = null): array
    {
        $userAgent = self::getAgent($userAgent);
        $result = [
            'agent' => $userAgent, //系统
            'os' => self::os($userAgent), //系统
            'browser' => '',//浏览器
            'robot' => 0,//浏览器
            'mobile' => 0,//是否手机端
            'device' => ''//设备
        ];
        if ($userAgent) {
            $agent = new Agent;
            $agent->setUserAgent($userAgent);
            $result['browser'] = $agent->browser() ?: '其他';
            $result['mobile'] = self::IsMobile($userAgent) ? 1 : 0;
            $result['device'] = $agent->device() ?: '其他';
            $result['robot'] = $agent->isRobot() ? 1 : 0;
        }
        return $result;
    }


    /**
     * 判断是否是移动端
     * @param string|null $userAgent
     * @return bool
     */
    public static function IsMobile(?string $userAgent = null): bool
    {
        $userAgent = self::getAgent($userAgent);
        $mobile_agents = array("Android", "iPhone", "iPod", "iPad", "Windows Phone", "BlackBerry", "Symbian", "Harmony");
        foreach ($mobile_agents as $mobile_agent) {
            if (str_contains($userAgent, $mobile_agent)) {
                return true;
            }
        }
        return false;
    }

}